package com.huluobo.base.mvvm

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import com.blankj.utilcode.util.ToastUtils
import java.lang.reflect.ParameterizedType

/**
 *  Created by LC on 2024/9/13.
 */
abstract class BaseActivity<VDB : ViewDataBinding, VM : BaseViewModel> : AppCompatActivity() {
    //拿到继承者泛型的集合,目前包含了2个参数 VDB和VM
    private val type by lazy { (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments }

    protected val binding: VDB by lazy {
        //找到第一个泛型,强转成对应的binding的类
        val clazz = type[0] as Class<VDB>
        //从泛型的类中通过反射拿到inflate的方法,准备填充布局
        val method = clazz.getMethod("inflate", LayoutInflater::class.java)
        //调用inflate方法,给自己填充布局,并且强转为当前布局,相当于setContentView(LayoutId)
        method.invoke(null, layoutInflater) as VDB
    }

    protected val vm: VM by lazy {
        //拿到第二个泛型,强转成VM
        val clazz = type[1] as Class<VM>
        //直接通过class来给vm赋值,由于需要的就是一个viewModel的class,所以直接赋值即可
        //比如LoginViewModel,这里传入的就是LoginViewModel::class.java
        ViewModelProvider(this)[clazz]
    }

    open fun onError(t: Throwable) {
        ToastUtils.showLong(t.message)
        Log.i("TagA", "错误信息:${t.message}")
        t.printStackTrace()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        vm.onFailed.observe(this, ::onError)
        initView()
        initData()
    }

    abstract fun initData()

    abstract fun initView()
}